package com.kwdb.sdk.query;

import com.kwdb.grpc.QueryResponse;
import com.kwdb.grpc.QueryRow;
import java.util.ArrayList;
import java.util.List;
import java.util.Iterator;

/**
 * 查询结果类
 */
public class QueryResult implements Iterable<QueryResult.Row> {
    
    private final List<String> columns;
    private final List<Row> rows;
    private final int totalCount;
    private final long executionTime;
    private final boolean hasMore;
    
    public QueryResult(List<String> columns, List<Row> rows, int totalCount, 
                      long executionTime, boolean hasMore) {
        this.columns = columns;
        this.rows = rows;
        this.totalCount = totalCount;
        this.executionTime = executionTime;
        this.hasMore = hasMore;
    }
    
    /**
     * 从gRPC响应创建QueryResult
     * @param response gRPC响应
     * @return QueryResult
     */
    public static QueryResult fromGrpcResponse(QueryResponse response) {
        List<String> columns = new ArrayList<>(response.getColumnsList());
        List<Row> rows = new ArrayList<>();
        
        for (QueryRow grpcRow : response.getRowsList()) {
            rows.add(Row.fromGrpcRow(grpcRow, columns));
        }
        
        return new QueryResult(columns, rows, response.getTotalCount(), 
                             response.getExecutionTimeMs(), response.getHasMore());
    }
    
    /**
     * 获取列名列表
     * @return 列名列表
     */
    public List<String> getColumns() {
        return columns;
    }
    
    /**
     * 获取行列表
     * @return 行列表
     */
    public List<Row> getRows() {
        return rows;
    }
    
    /**
     * 获取总行数
     * @return 总行数
     */
    public int getTotalCount() {
        return totalCount;
    }
    
    /**
     * 获取执行时间（毫秒）
     * @return 执行时间
     */
    public long getExecutionTime() {
        return executionTime;
    }
    
    /**
     * 是否还有更多数据
     * @return 是否还有更多数据
     */
    public boolean hasMore() {
        return hasMore;
    }
    
    /**
     * 检查是否为空结果
     * @return 是否为空
     */
    public boolean isEmpty() {
        return rows.isEmpty();
    }
    
    /**
     * 获取第一行数据
     * @return 第一行数据，如果没有数据则返回null
     */
    public Row getFirstRow() {
        return rows.isEmpty() ? null : rows.get(0);
    }
    
    /**
     * 获取指定索引的行
     * @param index 索引
     * @return 行数据
     */
    public Row getRow(int index) {
        if (index < 0 || index >= rows.size()) {
            throw new IndexOutOfBoundsException("索引超出范围: " + index);
        }
        return rows.get(index);
    }
    
    @Override
    public Iterator<Row> iterator() {
        return rows.iterator();
    }
    
    @Override
    public String toString() {
        return "QueryResult{" +
                "columns=" + columns +
                ", rowCount=" + rows.size() +
                ", totalCount=" + totalCount +
                ", executionTime=" + executionTime + "ms" +
                ", hasMore=" + hasMore +
                "}";
    }
    
    /**
     * 查询结果行类
     */
    public static class Row {
        private final List<String> values;
        private final List<String> columns;
        
        public Row(List<String> columns, List<String> values) {
            this.columns = columns;
            this.values = values;
        }
        
        /**
         * 从gRPC行创建Row
         * @param grpcRow gRPC行
         * @param columns 列名列表
         * @return Row
         */
        public static Row fromGrpcRow(QueryRow grpcRow, List<String> columns) {
            List<String> values = new ArrayList<>(grpcRow.getValuesList());
            return new Row(columns, values);
        }
        
        /**
         * 根据列名获取值
         * @param columnName 列名
         * @return 值
         */
        public String getValue(String columnName) {
            int index = columns.indexOf(columnName);
            if (index == -1) {
                return null;
            }
            return getValue(index);
        }
        
        /**
         * 根据索引获取值
         * @param index 索引
         * @return 值
         */
        public String getValue(int index) {
            if (index < 0 || index >= values.size()) {
                throw new IndexOutOfBoundsException("索引超出范围: " + index);
            }
            return values.get(index);
        }
        
        /**
         * 根据列名获取整数值
         * @param columnName 列名
         * @return 整数值
         */
        public Integer getInt(String columnName) {
            String value = getValue(columnName);
            if (value == null) {
                return null;
            }
            try {
                return Integer.parseInt(value);
            } catch (NumberFormatException e) {
                return null;
            }
        }
        
        /**
         * 根据列名获取长整数值
         * @param columnName 列名
         * @return 长整数值
         */
        public Long getLong(String columnName) {
            String value = getValue(columnName);
            if (value == null) {
                return null;
            }
            try {
                return Long.parseLong(value);
            } catch (NumberFormatException e) {
                return null;
            }
        }
        
        /**
         * 根据列名获取双精度浮点值
         * @param columnName 列名
         * @return 双精度浮点值
         */
        public Double getDouble(String columnName) {
            String value = getValue(columnName);
            if (value == null) {
                return null;
            }
            try {
                return Double.parseDouble(value);
            } catch (NumberFormatException e) {
                return null;
            }
        }
        
        /**
         * 根据列名获取布尔值
         * @param columnName 列名
         * @return 布尔值
         */
        public Boolean getBoolean(String columnName) {
            String value = getValue(columnName);
            if (value == null) {
                return null;
            }
            return Boolean.parseBoolean(value);
        }
        
        /**
         * 获取列数
         * @return 列数
         */
        public int getColumnCount() {
            return columns.size();
        }
        
        /**
         * 检查是否包含指定列
         * @param columnName 列名
         * @return 是否包含
         */
        public boolean hasColumn(String columnName) {
            return columns.contains(columnName);
        }
        
        @Override
        public String toString() {
            return "Row{" + values + "}";
        }
    }
}
